//
// @Auther: by wujehy
// @Email:wujehy@qq.com
// @Data:2020/9/12
// @Time:9:35 上午
//
//
#include <iostream>
#include <thread>
//#include "boost/asio.hpp"
#include "ClientService.h"
#include "glog/logging.h"
#include "ClientCmdFunction.h"
#include "ClientMod/TestClientMod.h"
#include "ClientMod/KeyValueClientMod.h"
using boost::asio::ip::tcp;
using namespace GeeJoan;
enum
{
    max_length = 1024
};

typedef void (*CallbackFunction)(ClientService *client);

std::map<std::string, CallbackFunction> m_function_msp;

void lsFunction(ClientService *appManager)
{
    for (auto f :m_function_msp)
    {
        std::cout << " cmd : " << f.first << std::endl;
    }
}

//　注册客户端方法
void registerFunction()
{
    //注册指令
    m_function_msp.insert({"calltest1", Test1Function});
    m_function_msp.insert({"calltest2", Test2Function});
    m_function_msp.insert({"calltest3", Test3Function});
    m_function_msp.insert({"showtime", ShowStartTimeFunction});
    m_function_msp.insert({"closelog", CloseLoggingFunction});
    m_function_msp.insert({"showlog", ShowLoggingFunction});
    m_function_msp.insert({"set", SetKeyValueFunction});
    m_function_msp.insert({"get", GetKeyValueFunction});
    m_function_msp.insert({"ls", lsFunction});
}

int main(int argc, char *argv[])
{
    registerFunction();
    FLAGS_log_dir = ".";

    google::InitGoogleLogging("client");
    google::SetStderrLogging(google::GLOG_INFO);
    try
    {
        if (argc != 3)
        {
            std::cerr << "Usage: chat_client <host> <port>\n";
            return 1;
        }
        std::cout << " init " << std::endl;
        boost::asio::io_context io_context;

        ClientService c(io_context);

        c.registerModFunc(new TestClientMod);
        c.registerModFunc(new KeyValueClientMod);

        c.setServeHost(argv[1]);
        c.setPort(argv[2]);

        c.connect_success_callback = [&]()
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            LOG(INFO) << " connect success ";
//            c.send("\1\1");
        };
        c.init();
        LOG(INFO) << " start ";
        std::thread t([&io_context]()
                      {
                          LOG(INFO) << " start run ";
                          io_context.run();
                          LOG(INFO) << "end ";
                      });
        ClientService *client = &c;
        std::thread t2([&]()
                       {
                           std::string inpucmd;
                           std::cout << " input `ls` show command list " << std::endl;
                           std::cout << ">>>" << std::flush;
                           while (true)
                           {
                               LOG(INFO) << " start input";

                               std::cin.clear();
                               inpucmd.clear();
                               std::cin >> inpucmd;
                               if (inpucmd == "q")
                               {

                                   client->close();
                                   io_context.stop();
                                   break;
                               }
                               auto find = m_function_msp.find(inpucmd);
                               if (find != m_function_msp.end())
                               {
                                   find->second(client);
                               } else
                               {
                                   LOG(INFO) << " not register function ";
                               }
                               std::cout << ">>>" << std::flush;
                           }
                       });


        t2.join();
        t.join();
    }
    catch (std::exception &e)
    {
        std::cerr << "Exception: " << e.what() << "\n";
    }

    return 0;
}